package com.jeehentor.system.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeehentor.common.vo.Result;
import com.jeehentor.dto.QueryLogFileDTO;
import com.jeehentor.dto.QuerySysLogDTO;
import com.jeehentor.entity.SysLog;
import com.jeehentor.system.service.ISysLogService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.util.*;

/**
 * <p>
 * 系统日志表 前端控制器
 * </p>
 *
 * @author wzd
 * @since 2024-04-01
 */
@RestController
@RequestMapping("/log")
@RequiredArgsConstructor
@Tag(name = "系统日志")
@Slf4j
public class SysLogController {

    private final ISysLogService sysLogService;

    @Operation(summary = "日志查询")
    @PostMapping("/pageList")
    public Result<Page<SysLog>> pageList(@RequestBody QuerySysLogDTO dto) {
        LambdaQueryWrapper<SysLog> sysLogLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysLogLambdaQueryWrapper.like(dto.getLogType() != null,SysLog::getLogType, dto.getLogType());
        sysLogLambdaQueryWrapper.like(StringUtils.isNotBlank(dto.getLogContent()),SysLog::getLogContent, dto.getLogContent());
        Page<SysLog> page = sysLogService.page(dto.getPage(), sysLogLambdaQueryWrapper);
        return Result.OK(page);
    }

    @Operation(summary = "日志文件列表")
    @PostMapping("/fileList")
    public Result<List<String>> fileList() {
        ArrayList<String> fileList = new ArrayList<>();
        // 根据提取的路径创建File对象
        File logDirectory = new File(getLogPath());

        // 列出目录中的所有文件（不包括子目录中的文件）
        File[] files = logDirectory.listFiles();

        // 检查files是否为null，防止目录路径错误
        if (files != null) {
            // 打印出每个文件的名称
            Arrays.stream(files).forEach(file -> fileList.add(file.getName()));
        } else {
            return Result.error("无日志文件!");
        }
        return Result.OK(CollectionUtil.reverse(fileList));
    }

    @Operation(summary = "日志文件列表")
    @PostMapping("/readLogLine")
    public Result<String> readLogLine(@RequestBody QueryLogFileDTO queryLogFileDTO) {
        StringBuilder logContent = new StringBuilder();
        File logFile = new File(getLogPath()+"/"+queryLogFileDTO.getFileName());
        String charset = "GBK";
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(logFile), charset))) {
            if("1".equals(queryLogFileDTO.getSort())){
                String line;
                int lineCount = 0;
                while ((line = reader.readLine()) != null && lineCount < Integer.parseInt(queryLogFileDTO.getLine())) {
                    logContent.append(line).append("\n");
                    lineCount++;
                }
            }else {
                // 使用LinkedList作为固定大小的队列
                Queue<String> lines = new LinkedList<>();
                String line;
                while ((line = reader.readLine()) != null) {
                    // 如果队列长度等于100，则移除最早的一行
                    if (lines.size() == Integer.parseInt(queryLogFileDTO.getLine())) {
                        lines.poll();
                    }
                    // 将新行添加到队列
                    lines.offer(line);
                }
                // 输出队列中的所有行，这些行是文件的最后100行
                for (String ln : lines) {
                    logContent.append(ln).append("\n");
                }
            }

        } catch (IOException e) {
            log.error("Error reading the file",e);
        }
        return Result.OK(logContent.toString());
    }

    private String getLogPath(){
        try {
            // 获取类加载器
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            // 使用类加载器从resources目录获取logback-spring.xml文件
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            // 通过类加载器的getResourceAsStream方法加载资源
            Document document = builder.parse(classLoader.getResourceAsStream("logback-spring.xml"));

            NodeList properties = document.getElementsByTagName("property");
            for (int i = 0; i < properties.getLength(); i++) {
                Element property = (Element) properties.item(i);
                if ("log_path".equals(property.getAttribute("name"))) {
                    return property.getAttribute("value");
                }
            }
            return "";
        }catch (Exception e){
            log.error("获取日志路径失败",e);
            return "";
        }
    }

}
